package com.zhuang.sms.netty.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

// 自定义处理器处理WebSocket消息
@ChannelHandler.Sharable
@Component
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    private static final Logger LOGGER = Logger.getLogger(TextWebSocketFrameHandler.class.getName());

    private static final Map<String, Channel> channels = new ConcurrentHashMap<>();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String ipPort = ctx.channel().remoteAddress().toString();
        String userId = generateUserId(ipPort); // 获取用户ID
        ctx.channel().attr(AttributeKey.valueOf("userId")).set(userId);
        channels.put(userId, ctx.channel());
        System.out.println("User " + userId + " connected!");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String userId = getUserIdFromContext(ctx);
        channels.remove(userId);
        System.out.println("User " + userId + " disconnected!");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        // 在这里处理接收到的消息
        LOGGER.log(Level.INFO, "Received message from WebSocket Client: {0}", msg.text());

        String userId = getUserIdFromContext(ctx);
        String messageContent = msg.text();

        // 解析消息内容以确定是一对一聊天还是群聊
        if (isPrivateMessage(messageContent)) {
            String targetUserId = extractTargetUserId(messageContent);
            Channel targetChannel = channels.get(targetUserId);
            if (targetChannel != null) {
                sendMessageToUser(targetChannel, messageContent);
            } else {
                // 目标用户不在线或其他错误处理
            }
        } else {
            broadcastMessage(messageContent);
        }

        // 发送响应到客户端
//        ctx.channel().writeAndFlush(new TextWebSocketFrame("Hello from Netty Server"));
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        LOGGER.log(Level.INFO, "WebSocket Client connected!");
        ctx.writeAndFlush("欢迎来到王者荣耀");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        LOGGER.log(Level.INFO, "WebSocket Client disconnected!");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }


    // 其他方法：生成或从上下文获取用户ID，解析消息内容判断是否私聊及提取目标用户ID，向特定用户发送消息，以及向所有在线用户广播消息

    private boolean isPrivateMessage(String messageContent) {
        // 根据你的协议解析消息内容，判断是否为私聊消息
        return false; // 示例返回，实际应替换为解析逻辑
    }

    private String extractTargetUserId(String messageContent) {
        // 从消息内容中提取目标用户的ID
        return ""; // 示例返回，实际应替换为提取逻辑
    }

    private void sendMessageToUser(Channel channel, String message) {
        channel.writeAndFlush(new TextWebSocketFrame(message));
    }

    private void broadcastMessage(String message) {
        for (Map.Entry<String, Channel> entry : channels.entrySet()) {
            Channel channel = entry.getValue();
            channel.writeAndFlush(new TextWebSocketFrame(message));
        }
    }


    // 假设我们从HTTP请求头或WebSocket连接时传递的参数中获取用户ID
    private String generateUserId(String ipPort) {
        // 在WebSocket握手阶段（例如：HTTP请求升级为WebSocket连接时），可以从HTTP请求的Header、Cookie或其他有效身份凭证中提取用户ID
        // 这是一个模拟实现，实际中应替换为你的认证和用户ID获取机制
        return "userId" + ipPort; // 临时返回一个固定值，实际应替换为实际用户ID
    }

    private String getUserIdFromContext(ChannelHandlerContext ctx) {
        // 这里假设我们在ChannelHandler的属性中存储了用户的ID
        return (String) ctx.channel().attr(AttributeKey.valueOf("userId")).get();
        // 或者你也可以通过自定义的协议，在WebSocket连接建立后，客户端发送的第一个消息中包含用户ID，然后在这里解析并保存到Channel的属性中
    }
}
